package com.gitee.wsl.ext.number

import kotlin.jvm.JvmName
import kotlin.math.abs

const val FUZZY_EQ_F = 1e-5f
const val FUZZY_EQ_D = 1e-10


 fun isFuzzyEqual(a: Float, b: Float, eps: Float = FUZZY_EQ_F) = (a - b).isFuzzyZero(eps)

 fun isFuzzyEqual(a: Double, b: Double, eps: Double = FUZZY_EQ_D) = (a - b).isFuzzyZero(eps)

@JvmName("isFuzzyEqual_F")
fun Float.isFuzzyEqual(b: Float, eps: Float = FUZZY_EQ_F) = isFuzzyEqual(this, b, eps)

infix fun Float.approx(x: Float): Boolean = isFuzzyEqual(x)

infix fun Double.approx(x: Double): Boolean = isFuzzyEqual(x)

@JvmName("isFuzzyEqual_D")
 fun Double.isFuzzyEqual(b: Double, eps: Double = FUZZY_EQ_D) = isFuzzyEqual(this, b, eps)

fun Float.isFuzzyZero(eps: Float = FUZZY_EQ_F) = abs(this) <= eps

fun Double.isFuzzyZero(eps: Double = FUZZY_EQ_D) = abs(this) <= eps

object DoubleApproxComparator : Comparator<Double> {
    override fun compare(a: Double, b: Double): Int {
        val d = a - b
        return when {
            abs(d) < FUZZY_EQ_D -> 0
            d < 0 -> -1
            else -> 1
        }
    }
}

val Double.Companion.ApproxComparator get() = DoubleApproxComparator

object FloatApproxComparator : Comparator<Float> {
    override fun compare(a: Float, b: Float): Int {
        val d = a - b
        return when {
            abs(d) < FUZZY_EQ_F -> 0
            d < 0 -> -1
            else -> 1
        }
    }
}

val Float.Companion.ApproxComparator get() = FloatApproxComparator
